home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / timidsrc.zip / timidity.c < prev    next >
C/C++ Source or Header  |  1997-02-11  |  19KB  |  775 lines

  1. /*
  2.  
  3.     TiMidity -- Experimental MIDI to WAVE converter
  4.     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
  5.  
  6.      This program is free software; you can redistribute it and/or modify
  7.      it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.      (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.      GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23.  
  24. #if defined(SOLARIS) || defined(__WIN32__)
  25. #include <string.h>
  26. #else
  27. #include <strings.h>
  28. #endif
  29.  
  30. #ifdef __WIN32__
  31. #include <windows.h>
  32. #define rindex strrchr
  33. extern int optind;
  34. extern char *optarg;
  35. int getopt(int, char **, char *);
  36. #else
  37. #include <unistd.h>
  38. #endif
  39.  
  40. #include "config.h"
  41. #include "common.h"
  42. #include "instrum.h"
  43. #include "playmidi.h"
  44. #include "readmidi.h"
  45. #include "output.h"
  46. #include "controls.h"
  47. #include "tables.h"
  48.  
  49. int free_instruments_afterwards=0;
  50. static char def_instr_name[256]="";
  51.  
  52. #ifdef __WIN32__
  53. int intr;
  54. CRITICAL_SECTION critSect;
  55.  
  56. #pragma argsused
  57. static BOOL WINAPI handler (DWORD dw)
  58.     {
  59.     printf ("***BREAK\n");
  60.     intr = TRUE;
  61.     play_mode->purge_output ();
  62.     return TRUE;
  63.     }
  64. #endif
  65.  
  66. static void help(void)
  67. {
  68.   PlayMode **pmp=play_mode_list;
  69.   ControlMode **cmp=ctl_list;
  70.   printf(" TiMidity version " TIMID_VERSION " (C) 1995 Tuukka Toivonen "
  71.      "<toivonen@clinet.fi>\n"
  72.      " TiMidity is free software and comes with ABSOLUTELY NO WARRANTY.\n"
  73.      "\n"
  74. #ifdef __WIN32__
  75.      " Win32 version by Davide Moretti <dmoretti@iper.net>\n"
  76.      "\n"
  77. #endif
  78.      "Usage:\n"
  79.      "  %s [options] filename [...]\n"
  80.      "\n"
  81. #ifndef __WIN32__        /*does not work in Win32 */
  82.      "  Use \"-\" as filename to read a MIDI file from stdin\n"
  83.      "\n"
  84. #endif
  85.      "Options:\n"
  86. #if defined(AU_HPUX)
  87.      "  -o file Output to another file (or audio server) (Use \"-\" for stdout)\n"
  88. #elif defined (AU_LINUX) 
  89.      "  -o file Output to another file (or device) (Use \"-\" for stdout)\n"
  90. #else
  91.      "  -o file Output to another file (Use \"-\" for stdout)\n"
  92. #endif
  93.      "  -O mode Select output mode and format (see below for list)\n"
  94.      "  -s f    Set sampling frequency to f (Hz or kHz)\n"
  95.      "  -a      Enable the antialiasing filter\n"
  96.      "  -f      "
  97. #ifdef FAST_DECAY
  98.                     "Disable"
  99. #else
  100.                     "Enable"
  101. #endif
  102.                               " fast decay mode\n"
  103.      "  -p n    Allow n-voice polyphony\n"
  104.      "  -A n    Amplify volume by n percent (may cause clipping)\n"
  105.      "  -C n    Set ratio of sampling and control frequencies\n"
  106.      "\n"
  107.      "  -L dir  Append dir to search path\n"
  108.      "  -c file Read extra configuration file\n"
  109.      "  -I n    Use program n as the default\n"
  110.      "  -P file Use patch file for all programs\n"
  111.      "  -D n    Play drums on channel n\n"
  112.      "  -Q n    Ignore channel n\n"
  113.      "  -F      Enable fast panning\n"
  114.      "  -U      Unload instruments from memory between MIDI files\n"
  115.      "\n"
  116.      "  -i mode Select user interface (see below for list)\n"
  117. #if defined(AU_LINUX) || defined(AU_WIN32) || defined(AU_DART)
  118.      "  -B n    Set number of buffer fragments\n"
  119. #endif
  120. #ifdef __WIN32__
  121.      "  -e      Increase thread priority (evil) - be careful!\n"
  122. #endif
  123.      "  -h      Display this help message\n"
  124.      "\n"
  125.      , program_name);
  126.  
  127.   printf("Available output modes (-O option):\n\n");
  128.   while (*pmp)
  129.      {
  130.         printf("  -O%c     %s\n", (*pmp)->id_character, (*pmp)->id_name);
  131.         pmp++;
  132.      }
  133.   printf("\nOutput format options (append to -O? option):\n\n"
  134.      "   `8'    8-bit sample width\n"
  135.      "   `1'    16-bit sample width\n"
  136.      "   `U'    uLaw encoding\n"
  137.      "   `l'    linear encoding\n"
  138.      "   `M'    monophonic\n"
  139.      "   `S'    stereo\n"
  140.      "   `s'    signed output\n"
  141.      "   `u'    unsigned output\n"
  142.      "   `x'    byte-swapped output\n");
  143. #ifdef AU_DART
  144.   printf("   `n'    do not use dynamic priority (nice)\n");
  145. #endif  
  146.   
  147.   printf("\nAvailable interfaces (-i option):\n\n");
  148.   while (*cmp)
  149.      {
  150.       printf("  -i%c     %s\n", (*cmp)->id_character, (*cmp)->id_name);
  151.       cmp++;
  152.      }
  153.   printf("\nInterface options (append to -i? option):\n\n"
  154.      "   `v'    more verbose (cumulative)\n"
  155.      "   `q'    quieter (cumulative)\n"
  156.      "   `t'    trace playing\n\n");
  157. }
  158.  
  159. static void interesting_message(void)
  160. {
  161.   printf(
  162. "\n"
  163. " TiMidity version " TIMID_VERSION " -- Experimental MIDI to WAVE converter\n"
  164. " Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>\n"
  165. " \n"
  166. #ifdef __WIN32__
  167. " Win32 version by Davide Moretti <dmoretti@iper.net>\n"
  168. "\n"
  169. #endif
  170. " This program is free software; you can redistribute it and/or modify\n"
  171. " it under the terms of the GNU General Public License as published by\n"
  172. " the Free Software Foundation; either version 2 of the License, or\n"
  173. " (at your option) any later version.\n"
  174. " \n"
  175. " This program is distributed in the hope that it will be useful,\n"
  176. " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  177. " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  178. " GNU General Public License for more details.\n"
  179. " \n"
  180. " You should have received a copy of the GNU General Public License\n"
  181. " along with this program; if not, write to the Free Software\n"
  182. " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
  183. "\n"
  184. );
  185.  
  186. }
  187.  
  188. static int set_channel_flag(int32 *flags, int32 i, char *name)
  189. {
  190.   if (i==0) *flags=0;
  191.   else if ((i<1 || i>16) && (i<-16 || i>-1))
  192.     {
  193.         fprintf(stderr,
  194.           "%s must be between 1 and 16, or between -1 and -16, or 0\n", 
  195.           name);
  196.       return -1;
  197.      }
  198.   else
  199.     {
  200.       if (i>0) *flags |= (1<<(i-1));
  201.         else *flags &= ~ ((1<<(-1-i)));
  202.     }
  203.   return 0;
  204. }
  205.  
  206. static int set_value(int32 *param, int32 i, int32 low, int32 high, char *name)
  207. {
  208.   if (i<low || i > high)
  209.     {
  210.       fprintf(stderr, "%s must be between %ld and %ld\n", name, low, high);
  211.       return -1;
  212.     }
  213.   else *param=i;
  214.   return 0;
  215. }
  216.  
  217. static int set_play_mode(char *cp)
  218. {
  219.   PlayMode *pmp, **pmpp=play_mode_list;
  220.  
  221.   while ((pmp=*pmpp++))
  222.     {
  223.       if (pmp->id_character == *cp)
  224.     {
  225.       play_mode=pmp;
  226.       while (*(++cp))
  227.          switch(*cp)
  228.           {
  229.           case 'U': pmp->encoding |= PE_ULAW; break; /* uLaw */
  230.             case 'l': pmp->encoding &= ~PE_ULAW; break; /* linear */
  231.  
  232.             case '1': pmp->encoding |= PE_16BIT; break; /* 1 for 16-bit */
  233.           case '8': pmp->encoding &= ~PE_16BIT; break;
  234.  
  235.           case 'M': pmp->encoding |= PE_MONO; break;
  236.           case 'S': pmp->encoding &= ~PE_MONO; break; /* stereo */
  237.  
  238.           case 's': pmp->encoding |= PE_SIGNED; break;
  239.           case 'u': pmp->encoding &= ~PE_SIGNED; break;
  240.  
  241.           case 'x': pmp->encoding ^= PE_BYTESWAP; break; /* toggle */
  242. #ifdef AU_DART
  243.           case 'n': pmp->extra_param[1]=0; break;
  244. #endif         
  245.  
  246.             default:
  247.         fprintf(stderr, "Unknown format modifier `%c'\n", *cp);
  248.         return 1;
  249.           }
  250.       return 0;
  251.     }
  252.      }
  253.   
  254.   fprintf(stderr, "Playmode `%c' is not compiled in.\n", *cp);
  255.   return 1;
  256. }
  257.  
  258. static int set_ctl(char *cp)
  259. {
  260.   ControlMode *cmp, **cmpp=ctl_list;
  261.  
  262.   while ((cmp=*cmpp++))
  263.     {
  264.       if (cmp->id_character == *cp)
  265.     {
  266.       ctl=cmp;
  267.       while (*(++cp))
  268.         switch(*cp)
  269.             {
  270.             case 'v': cmp->verbosity++; break;
  271.           case 'q': cmp->verbosity--; break;
  272.             case 't': /* toggle */
  273.         cmp->trace_playing= (cmp->trace_playing) ? 0 : 1; 
  274.         break;
  275.  
  276.           default:
  277.         fprintf(stderr, "Unknown interface option `%c'\n", *cp);
  278.         return 1;
  279.           }
  280.       return 0;
  281.     }
  282.      }
  283.   
  284.   fprintf(stderr, "Interface `%c' is not compiled in.\n", *cp);
  285.   return 1;
  286. }
  287.  
  288. #define MAXWORDS 10
  289.  
  290. static int read_config_file(char *name)
  291. {
  292.   FILE *fp;
  293.   char tmp[1024], *w[MAXWORDS], *cp;
  294.   ToneBank *bank=0;
  295.   int i, j, k, line=0, words;
  296.   static int rcf_count=0;
  297.  
  298.   if (rcf_count>50)
  299.      {
  300.         fprintf(stderr, "Probable source loop in configuration files");
  301.         return (-1);
  302.      }
  303.  
  304.   if (!(fp=open_file(name, 1, OF_VERBOSE)))
  305.      return -1;
  306.  
  307.   while (fgets(tmp, sizeof(tmp), fp))
  308.      {
  309. #ifdef __EMX__
  310.         words=strlen(tmp)-1;
  311.         if (tmp[0]=='\26') tmp[0]='\0';
  312. #endif        
  313.       line++;
  314.         w[words=0]=strtok(tmp, " \t\r\n\240\032");
  315.         if (!w[0] || (*w[0]=='#')) continue;
  316.       while (w[words] && (words < MAXWORDS))
  317.     w[++words]=strtok(0," \t\r\n\240\032");
  318.       if (!strcmp(w[0], "dir"))
  319.     {
  320.       if (words < 2)
  321.          {
  322.           fprintf(stderr, "%s: line %d: No directory given\n", name, line);
  323.           return -2;
  324.          }
  325.       for (i=1; i<words; i++)
  326.         add_to_pathlist(w[i]);
  327.     }
  328.         else if (!strcmp(w[0], "source"))
  329.     {
  330.       if (words < 2)
  331.         {
  332.           fprintf(stderr, "%s: line %d: No file name given\n", name, line);
  333.           return -2;
  334.          }
  335.       for (i=1; i<words; i++)
  336.         {
  337.           rcf_count++;
  338.             read_config_file(w[i]);
  339.           rcf_count--;
  340.         }
  341.     }
  342.       else if (!strcmp(w[0], "default"))
  343.     {
  344.       if (words != 2)
  345.         {
  346.           fprintf(stderr, 
  347.                 "%s: line %d: Must specify exactly one patch name\n",
  348.               name, line);
  349.           return -2;
  350.         }
  351.       strncpy(def_instr_name, w[1], 255);
  352.       def_instr_name[255]='\0';
  353.     }
  354.         else if (!strcmp(w[0], "drumset"))
  355.     {
  356.       if (words < 2)
  357.         {
  358.           fprintf(stderr, "%s: line %d: No drum set number given\n", 
  359.               name, line);
  360.             return -2;
  361.         }
  362.       i=atoi(w[1]);
  363.       if (i<0 || i>127)
  364.          {
  365.           fprintf(stderr, 
  366.               "%s: line %d: Drum set must be between 0 and 127\n",
  367.                 name, line);
  368.           return -2;
  369.          }
  370.       if (!drumset[i])
  371.         {
  372.           drumset[i]=safe_malloc(sizeof(ToneBank));
  373.             memset(drumset[i], 0, sizeof(ToneBank));
  374.          }
  375.       bank=drumset[i];
  376.     }
  377.         else if (!strcmp(w[0], "bank"))
  378.     {
  379.       if (words < 2)
  380.          {
  381.           fprintf(stderr, "%s: line %d: No bank number given\n", 
  382.                 name, line);
  383.           return -2;
  384.          }
  385.       i=atoi(w[1]);
  386.       if (i<0 || i>127)
  387.         {
  388.           fprintf(stderr, 
  389.               "%s: line %d: Tone bank must be between 0 and 127\n",
  390.                 name, line);
  391.           return -2;
  392.         }
  393.       if (!tonebank[i])
  394.          {
  395.             tonebank[i]=safe_malloc(sizeof(ToneBank));
  396.           memset(tonebank[i], 0, sizeof(ToneBank));
  397.         }
  398.       bank=tonebank[i];
  399.     }
  400.       else {
  401.     if ((words < 2) || (*w[0] < '0' || *w[0] > '9'))
  402.       {
  403.          fprintf(stderr, "%s: line %d: syntax error\n", name, line);
  404.          return -2;
  405.       }
  406.     i=atoi(w[0]);
  407.     if (i<0 || i>127)
  408.       {
  409.         fprintf(stderr, "%s: line %d: Program must be between 0 and 127\n",
  410.             name, line);
  411.         return -2;
  412.       }
  413.     if (!bank)
  414.       {
  415.         fprintf(stderr, 
  416.              "%s: line %d: Must specify tone bank or drum set "
  417.             "before assignment\n",
  418.             name, line);
  419.          return -2;
  420.       }
  421.     if (bank->tone[i].name)
  422.       free(bank->tone[i].name);
  423.     strcpy((bank->tone[i].name=safe_malloc(strlen(w[1])+1)),w[1]);
  424.     bank->tone[i].note=bank->tone[i].amp=bank->tone[i].pan=
  425.       bank->tone[i].strip_loop=bank->tone[i].strip_envelope=
  426.         bank->tone[i].strip_tail=-1;
  427.  
  428.     for (j=2; j<words; j++)
  429.       {
  430.         if (!(cp=strchr(w[j], '=')))
  431.           {
  432.         fprintf(stderr, "%s: line %d: bad patch option %s\n",
  433.             name, line, w[j]);
  434.         return -2;
  435.           }
  436.         *cp++=0;
  437.         if (!strcmp(w[j], "amp"))
  438.             {
  439.         k=atoi(cp);
  440.         if ((k<0 || k>MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9'))
  441.           {
  442.              fprintf(stderr,
  443.                 "%s: line %d: amplification must be between "
  444.                  "0 and %d\n", name, line, MAX_AMPLIFICATION);
  445.              return -2;
  446.           }
  447.         bank->tone[i].amp=k;
  448.           }
  449.         else if (!strcmp(w[j], "note"))
  450.           {
  451.         k=atoi(cp);
  452.         if ((k<0 || k>127) || (*cp < '0' || *cp > '9'))
  453.           {
  454.              fprintf(stderr,
  455.                  "%s: line %d: note must be between 0 and 127\n",
  456.                 name, line);
  457.             return -2;
  458.           }
  459.         bank->tone[i].note=k;
  460.             }
  461.          else if (!strcmp(w[j], "pan"))
  462.             {
  463.         if (!strcmp(cp, "center"))
  464.           k=64;
  465.         else if (!strcmp(cp, "left"))
  466.           k=0;
  467.         else if (!strcmp(cp, "right"))
  468.           k=127;
  469.         else
  470.           k=((atoi(cp)+100) * 100) / 157;
  471.         if ((k<0 || k>127) ||
  472.              (k==0 && *cp!='-' && (*cp < '0' || *cp > '9')))
  473.           {
  474.              fprintf(stderr,
  475.                  "%s: line %d: panning must be left, right, "
  476.                  "center, or between -100 and 100\n",
  477.                  name, line);
  478.              return -2;
  479.           }
  480.         bank->tone[i].pan=k;
  481.             }
  482.          else if (!strcmp(w[j], "keep"))
  483.             {
  484.         if (!strcmp(cp, "env"))
  485.           bank->tone[i].strip_envelope=0;
  486.         else if (!strcmp(cp, "loop"))
  487.           bank->tone[i].strip_loop=0;
  488.         else
  489.           {
  490.              fprintf(stderr, "%s: line %d: keep must be env or loop\n",
  491.                  name, line);
  492.              return -2;
  493.           }
  494.             }
  495.          else if (!strcmp(w[j], "strip"))
  496.             {
  497.         if (!strcmp(cp, "env"))
  498.           bank->tone[i].strip_envelope=1;
  499.         else if (!strcmp(cp, "loop"))
  500.           bank->tone[i].strip_loop=1;
  501.         else if (!strcmp(cp, "tail"))
  502.           bank->tone[i].strip_tail=1;
  503.         else
  504.           {
  505.              fprintf(stderr, "%s: line %d: strip must be env, loop, or tail\n",
  506.                  name, line);
  507.              return -2;
  508.           }
  509.             }
  510.          else
  511.             {
  512.         fprintf(stderr, "%s: line %d: bad patch option %s\n",
  513.             name, line, w[j]);
  514.         return -2;
  515.             }
  516.       }
  517.         }
  518.      }
  519.   if (ferror(fp))
  520.      {
  521.         fprintf(stderr, "Can't read %s: %s\n", name, sys_errlist[errno]);
  522.         close_file(fp);
  523.         return -2;
  524.      }
  525.   close_file(fp);
  526.   return 0;
  527. }
  528. #ifdef __WIN32__
  529. int __cdecl main(int argc, char **argv)
  530. #else
  531. int main(int argc, char **argv)
  532. #endif
  533. {
  534.   int
  535.      c, cmderr=0, i, got_a_configuration=0, try_config_again=0,
  536.      need_stdin=0, need_stdout=0;
  537.  
  538.   int32
  539.      tmpi32, output_rate=DEFAULT_RATE;
  540.  
  541.   char
  542.      *output_name=0;
  543.  
  544. #if defined(AU_LINUX) || defined(AU_WIN32) || defined(AU_DART)
  545.   int buffer_fragments=-1;
  546. #endif
  547.  
  548. #ifdef __WIN32__
  549.     int evil=0;
  550. #endif
  551.  
  552. #ifdef DANGEROUS_RENICE
  553. #include <sys/resource.h>
  554.   int u_uid=getuid();
  555.   if (setpriority(PRIO_PROCESS, 0, DANGEROUS_RENICE) < 0)
  556.      fprintf(stderr, "Couldn't set priority to %d.\n", DANGEROUS_RENICE);
  557.   setreuid(u_uid, u_uid);
  558. #endif
  559. #ifdef __EMX__
  560.   _wildcard(&argc,&argv);
  561. #endif
  562.   if ((program_name=rindex(argv[0], '/'))) program_name++;
  563.   else program_name=argv[0];
  564. #if !defined(PM)  
  565.   if (argc==1)
  566.      {
  567.         interesting_message();
  568.         return 0;
  569.      }
  570. #endif
  571.   
  572.   if (!read_config_file(CONFIG_FILE))
  573.      got_a_configuration=1;
  574.  
  575.   while ((c=getopt(argc, argv, "UI:P:L:c:A:C:ap:fo:O:s:Q:FD:hi:"
  576. #if defined(AU_LINUX) || defined(AU_WIN32) || defined(AU_DART)
  577.             "B:" /* buffer fragments */
  578. #endif
  579. #ifdef __WIN32__
  580.             "e"    /* evil (be careful) */
  581. #endif
  582.             ))>0)
  583.      switch(c)
  584.         {
  585.         case 'U': free_instruments_afterwards=1; break;
  586.         case 'L': add_to_pathlist(optarg); try_config_again=1; break;
  587.         case 'c':
  588.     if (read_config_file(optarg)) cmderr++;
  589.     else got_a_configuration=1;
  590.     break;
  591.  
  592.         case 'Q':
  593.     if (set_channel_flag(&quietchannels, atoi(optarg), "Quiet channel"))
  594.       cmderr++;
  595.     break;
  596.  
  597.         case 'D':
  598.     if (set_channel_flag(&drumchannels, atoi(optarg), "Drum channel"))
  599.       cmderr++;
  600.     break;
  601.  
  602.         case 'O': /* output mode */
  603.     if (set_play_mode(optarg))
  604.       cmderr++;
  605.     break;
  606.  
  607.         case 'o':    output_name=optarg; break;
  608.  
  609.         case 'a': antialiasing_allowed=1; break;
  610.  
  611.         case 'f': fast_decay=(fast_decay) ? 0 : 1; break;
  612.  
  613.         case 'F': adjust_panning_immediately=1; break;
  614.  
  615.         case 's': /* sampling rate */
  616.     i=atoi(optarg);
  617.     if (i < 100) i *= 1000;
  618.     if (set_value(&output_rate, i, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE,
  619.                 "Resampling frequency")) cmderr++;
  620.     break;
  621.  
  622.         case 'P': /* set overriding instrument */
  623.     strncpy(def_instr_name, optarg, 255);
  624.     def_instr_name[255]='\0';
  625.     break;
  626.  
  627.         case 'I':
  628.     if (set_value(&tmpi32, atoi(optarg), 0, 127,
  629.                 "Default program")) cmderr++;
  630.     else default_program=tmpi32;
  631.     break;
  632.         case 'A':
  633.     if (set_value(&lification, atoi(optarg), 1, MAX_AMPLIFICATION,
  634.                 "Amplification")) cmderr++;
  635.     break;
  636.         case 'C':
  637.     if (set_value(&control_ratio, atoi(optarg), 1, MAX_CONTROL_RATIO,
  638.                 "Control ratio")) cmderr++;
  639.     break;
  640.         case 'p':
  641.     if (set_value(&tmpi32, atoi(optarg), 1, MAX_VOICES,
  642.                 "Polyphony")) cmderr++;
  643.     else voices=tmpi32;
  644.     break;
  645.  
  646.         case 'i':
  647.     if (set_ctl(optarg))
  648.       cmderr++;
  649. #if defined(AU_LINUX) || defined(AU_WIN32)
  650.     else if (buffer_fragments==-1 && ctl->trace_playing)
  651.       /* user didn't specify anything, so use 2 for real-time response */
  652. #if defined(AU_LINUX)
  653.       buffer_fragments=2;
  654. #else
  655.         buffer_fragments=3;        /* On Win32 2 is chunky */
  656. #endif
  657. #endif
  658.     break;
  659.  
  660. #if defined(AU_LINUX) || defined(AU_WIN32) || defined(AU_DART)
  661.         case 'B':
  662.     if (set_value(&tmpi32, atoi(optarg), 0,
  663. #ifdef AU_DART
  664.               100,
  665. #else              
  666.               1000,
  667. #endif              
  668.                 "Buffer fragments")) cmderr++;
  669.     else buffer_fragments=tmpi32;
  670.     break;
  671. #endif
  672. #ifdef __WIN32__
  673.         case 'e': /* evil */
  674.             evil = 1;
  675.             break;
  676. #endif
  677.         case 'h':
  678.     help();
  679.     return 0;
  680.  
  681.         default:
  682.     cmderr++; break;
  683.         }
  684.  
  685.   if (!got_a_configuration)
  686.      {
  687.         if (!try_config_again || read_config_file(CONFIG_FILE))
  688.     cmderr++;
  689.      }
  690.  
  691.   /* If there were problems, give up now */
  692.   if (cmderr
  693. #if !defined(PM)      
  694.       || optind >= argc
  695. #endif      
  696.       )
  697.      {
  698.         fprintf(stderr, "Try %s -h for help\n", program_name);
  699.         return 1; /* problems with command line */
  700.      }
  701.  
  702.   /* Set play mode parameters */
  703.   play_mode->rate=output_rate;
  704.   if (output_name)
  705.      {
  706.         play_mode->name=output_name;
  707.         if (!strcmp(output_name, "-"))
  708.     need_stdout=1;
  709.      }
  710. #if defined(AU_LINUX) || defined(AU_WIN32) || defined(AU_DART)
  711.   if (buffer_fragments != -1)
  712.      play_mode->extra_param[0]=buffer_fragments;
  713. #endif
  714.  
  715.   init_tables();
  716.  
  717. #if !defined(PM)
  718.   if (optind<argc)
  719. #endif     
  720.      {
  721.         int orig_optind=optind;
  722.  
  723.         while (optind<argc)
  724.     if (!strcmp(argv[optind++], "-"))
  725.       need_stdin=1;
  726.         optind=orig_optind;
  727.  
  728.         if (ctl->open(need_stdin, need_stdout))
  729.     {
  730.       fprintf(stderr, "Couldn't open %s\n", ctl->id_name);
  731.       play_mode->close_output();
  732.       return 3;
  733.     }
  734.         /* Open output device */
  735.         if (play_mode->open_output()<0)
  736.     {
  737.       fprintf(stderr, "Couldn't open %s\n", play_mode->id_name);
  738.       ctl->close();
  739.       return 2;
  740.     }
  741.  
  742.         if (!control_ratio)
  743.     {
  744.       control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
  745.       if(control_ratio<1)
  746.          control_ratio=1;
  747.       else if (control_ratio > MAX_CONTROL_RATIO)
  748.          control_ratio=MAX_CONTROL_RATIO;
  749.     }
  750.  
  751.         if (*def_instr_name)
  752.     set_default_instrument(def_instr_name);
  753.  
  754. #ifdef __WIN32__
  755.         SetConsoleCtrlHandler (handler, TRUE);
  756.         InitializeCriticalSection (&critSect);
  757.         if(evil)
  758.             if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL))
  759.                 fprintf(stderr, "Error raising process priority.\n");
  760. #endif
  761.  
  762.         /* Return only when quitting */
  763.         ctl->pass_playing_list(argc-optind, &argv[orig_optind]);
  764.  
  765.         play_mode->close_output();
  766.         ctl->close();
  767. #ifdef __WIN32__
  768.             DeleteCriticalSection (&critSect);
  769. #endif
  770.         return 0;
  771.  
  772.      }
  773.   return 0;
  774. }
  775.